package com.zx.task.manager.service.impl;

import com.zx.core.enums.StatusEnum;
import com.zx.core.page.PageInfo;
import com.zx.core.wrapper.ObjectWrapper;
import com.zx.core.wrapper.PageWrapper;
import com.zx.core.wrapper.ResponseWrapper;
import com.zx.feign.client.SystemClient;
import com.zx.feign.client.dto.GetSysUserResponseDTO;
import com.zx.security.block.uitls.SecurityUtils;
import com.zx.task.manager.components.NotificationComponent;
import com.zx.task.manager.dao.TaskOperationsMapper;
import com.zx.task.manager.dao.TaskTypesMapper;
import com.zx.task.manager.dao.TasksMapper;
import com.zx.task.manager.enums.*;
import com.zx.task.manager.mapstruct.TasksMapStructMapper;
import com.zx.task.manager.model.TaskOperations;
import com.zx.task.manager.model.TaskTypes;
import com.zx.task.manager.model.Tasks;
import com.zx.task.manager.param.TaskOperationsParam;
import com.zx.task.manager.param.TasksParam;
import com.zx.task.manager.service.ITasksService;
import com.zx.task.manager.utils.TaskNoUtils;
import com.zx.task.manager.vo.TasksVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * description: 任务服务实现类 <br>
 * create: 2025-10-13 20:15
 * </p>
 *
 * @author zhou  xun
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TasksServiceImpl implements ITasksService {
    private final TasksMapper tasksMapper;
    private final TaskTypesMapper taskTypesMapper;
    private final TaskOperationsMapper taskOperationsMapper;
    private final SystemClient systemClient;
    private final NotificationComponent notificationComponent;

    @Override
    public PageWrapper<TasksVO> getTasksVOListByPage(TasksParam tasksParam) {
        PageWrapper<TasksVO> result = new PageWrapper<>();
        try {
            PageInfo pageInfo = new PageInfo(tasksParam.getPageNum(), tasksParam.getPageSize());
            tasksParam.setPageNum(pageInfo.getPageNum());
            tasksParam.setPageSize(pageInfo.getPageSize());

            // 查询总数
            Long count = tasksMapper.getTasksListCount(tasksParam.getTaskNo(),
                    tasksParam.getTitle(),
                    tasksParam.getTaskTypeId(),
                    tasksParam.getPriority(),
                    tasksParam.getStatus(),
                    tasksParam.getCreateTimeStart(),
                    tasksParam.getCreateTimeEnd());
            if (count > 0) {
                // 分页查询列表
                List<Tasks> tasksList = tasksMapper.getTasksListByPage(tasksParam.getTaskNo(),
                        tasksParam.getTitle(),
                        tasksParam.getTaskTypeId(),
                        tasksParam.getPriority(),
                        tasksParam.getStatus(),
                        tasksParam.getCreateTimeStart(),
                        tasksParam.getCreateTimeEnd(),
                        tasksParam.getPageNum(),
                        tasksParam.getPageSize());

                // 获取所有相关的任务类型ID
                List<String> taskTypeIds = tasksList.stream()
                        .map(Tasks::getTaskTypeId)
                        .filter(Objects::nonNull)
                        .distinct()
                        .toList();

                // 批量查询任务类型信息
                Map<String, String> taskTypeMap = taskTypeIds.isEmpty() ? Map.of() :
                        taskTypesMapper.selectTaskTypesList(null).stream()
                                .collect(Collectors.toMap(TaskTypes::getId, TaskTypes::getTypeName));

                // 批量查询任务类型颜色信息
                Map<String, String> taskTypeColorMap = taskTypeIds.isEmpty() ? Map.of() :
                        taskTypesMapper.selectTaskTypesList(null).stream()
                                .filter(taskType -> taskType.getColor() != null)
                                .collect(Collectors.toMap(TaskTypes::getId, TaskTypes::getColor));

                // 转换为VO并设置任务类型名称
                List<TasksVO> list = tasksList.stream()
                        .map(task -> {
                            TasksVO tasksVO = TasksMapStructMapper.INSTANCE.tasksToTasksVO(task);
                            // 设置任务类型名称
                            if (task.getTaskTypeId() != null) {
                                tasksVO.setTaskTypeName(taskTypeMap.get(task.getTaskTypeId()));
                                tasksVO.setTaskTypeColor(taskTypeColorMap.get(task.getTaskTypeId()));
                            }
                            // 设置是否有子任务
                            List<Tasks> children = tasksMapper.selectTasksByParentId(task.getId());
                            tasksVO.setHasChildren(children != null && !children.isEmpty());
                            return tasksVO;
                        })
                        .toList();

                // 设置返回结果
                result.setData(list);
            }
            result.setTotal(count);
            result.setCurrentPageNum(tasksParam.getPageNum());
            result.setTotalPage(pageInfo);
        } catch (Exception e) {
            log.error("获取任务列表时发生错误", e);
            result.fail("获取任务列表时发生错误: " + e.getMessage());
        }

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper addTask(TasksParam tasksParam) {
        ResponseWrapper result = new ResponseWrapper();

        // 验证参数
        ResponseWrapper validationResponse = validateTaskParams(tasksParam);
        if (validationResponse.verifyFail()) {
            return validationResponse;
        }

        // 验证父任务相关参数
        ResponseWrapper parentValidationResult = validateParentTask(tasksParam);
        if (parentValidationResult.verifyFail()) {
            return parentValidationResult;
        }

        //创建任务信息对象
        Tasks tasks = TasksMapStructMapper.INSTANCE.tasksParamToTasks(tasksParam);
        tasks.setId(TaskNoUtils.generateTaskId());

        // 自动生成任务编号
        String taskNo = TaskNoUtils.generateTaskNo();
        tasks.setTaskNo(taskNo);

        //设置创建信息
        tasks.setCreatorId(SecurityUtils.getUserId());
        tasks.setCreatorName(SecurityUtils.getUserName());
        //设置状态不用前端传递,防止状态错误,设置为待发布
        tasks.setStatus(TaskStatusEnum.PENDING_RELEASE.getCode());
        tasks.setCreateBy(SecurityUtils.getUserId());
        tasks.setCreateTime(LocalDateTime.now());

        // 插入任务到数据库
        tasksMapper.insertSelective(tasks);

        // 记录任务创建操作
        TaskOperations taskOperation = TaskOperations.builder()
                .id(TaskNoUtils.generateTaskId())
                .taskId(tasks.getId())
                .operationType(TaskOperationTypeEnum.CREATE.getCode())
                .operatorId(SecurityUtils.getUserId())
                .operatorName(SecurityUtils.getUserName())
                .remark("任务创建成功")
                .createTime(LocalDateTime.now())
                .build();
        taskOperationsMapper.insertSelective(taskOperation);

        return result;
    }

    /**
     * 验证任务参数
     *
     * @param tasksParam 任务参数
     * @return 验证结果
     */
    private ResponseWrapper validateTaskParams(TasksParam tasksParam) {
        ResponseWrapper result = new ResponseWrapper();

        //验证优先级是否正确
        TaskPriorityEnum taskPriorityEnum = TaskPriorityEnum.getEnumByCode(tasksParam.getPriority());
        if (null == taskPriorityEnum) {
            result.fail("传入的优先级错误!");
            return result;
        }

        // 验证通用任务参数
        ResponseWrapper commonValidationResult = validateCommonTaskParams(tasksParam);
        if (commonValidationResult.verifyFail()) {
            return commonValidationResult;
        }

        return result;
    }

    /**
     * 验证编辑任务时的参数
     *
     * @param tasksParam 任务参数
     * @return 验证结果
     */
    private ResponseWrapper validateTaskParamsForEdit(TasksParam tasksParam) {
        ResponseWrapper result = new ResponseWrapper();

        // 验证通用任务参数
        ResponseWrapper commonValidationResult = validateCommonTaskParams(tasksParam);
        if (commonValidationResult.verifyFail()) {
            return commonValidationResult;
        }

        return result;
    }

    /**
     * 验证添加子任务时的参数
     *
     * @param tasksParam 任务参数
     * @return 验证结果
     */
    private ResponseWrapper validateChildTaskParams(TasksParam tasksParam) {
        ResponseWrapper result = new ResponseWrapper();

        // 验证参数
        ResponseWrapper validationResponse = validateTaskParams(tasksParam);
        if (validationResponse.verifyFail()) {
            return validationResponse;
        }

        // 验证父任务相关参数
        ResponseWrapper parentValidationResult = validateParentTask(tasksParam);
        if (parentValidationResult.verifyFail()) {
            return parentValidationResult;
        }

        // 验证父任务是否存在
        if (tasksParam.getParentId() == null || tasksParam.getParentId().isEmpty()) {
            result.fail("添加子任务时必须指定父任务ID!");
            return result;
        }

        Tasks parentTask = tasksMapper.selectByPrimaryKey(tasksParam.getParentId());
        if (parentTask == null) {
            result.fail("指定的父任务不存在!");
            return result;
        }

        // 验证当前用户是否为父任务创建者，只有父任务创建者才能创建子任务
        if (!parentTask.getCreatorId().equals(SecurityUtils.getUserId())) {
            result.fail("只有父任务创建者才能为其创建子任务!");
            return result;
        }

        return result;
    }

    /**
     * 验证通用任务参数（任务类型、严重程度、处理人信息、时间等）
     *
     * @param tasksParam 任务参数
     * @return 验证结果
     */
    private ResponseWrapper validateCommonTaskParams(TasksParam tasksParam) {
        ResponseWrapper result = new ResponseWrapper();

        // 验证任务类型是否存在
        TaskTypes taskTypes = taskTypesMapper.selectByPrimaryKey(tasksParam.getTaskTypeId());
        if (taskTypes == null) {
            result.fail("传入的任务类型不存在!");
            return result;
        }

        //验证任务类型状态
        if (!Objects.equals(taskTypes.getStatus(), StatusEnum.ENABLE.getCode())) {
            result.fail("设置的任务类型未启用!");
            return result;
        }

        // 验证任务类型编码是否有效
        TaskTypeEnum taskTypeEnum = TaskTypeEnum.getEnumByCode(taskTypes.getTypeCode());
        if (taskTypeEnum == null) {
            result.fail("任务类型编码无效!");
            return result;
        }

        // 根据任务类型判断是否需要验证严重程度
        if ("BUG".equals(taskTypes.getTypeCode())) {
            // 对于缺陷类型任务，严重程度是必需的
            if (tasksParam.getSeverity() == null) {
                result.fail("缺陷类型任务必须指定严重程度!");
                return result;
            }

            // 验证严重程度值是否有效
            TaskSeverityEnum taskSeverityEnum = TaskSeverityEnum.getEnumByCode(tasksParam.getSeverity());
            if (taskSeverityEnum == null) {
                result.fail("传入的严重程度值无效!");
                return result;
            }
        } else {
            // 非缺陷类型任务不应设置严重程度
            if (tasksParam.getSeverity() != null) {
                result.fail("非缺陷类型任务不应设置严重程度!");
                return result;
            }
        }

        //验证指定的处理人是否存在,姓名是否正确
        ResponseWrapper userValidationResult = validateAssigneeInfo(tasksParam);
        if (userValidationResult.verifyFail()) {
            return userValidationResult;
        }

        // 验证计划开始时间和结束时间 必须开始时间小于结束时间
        // 允许开始时间和结束时间相同
        if (tasksParam.getPlannedStartTime() != null && tasksParam.getPlannedEndTime() != null
                && tasksParam.getPlannedStartTime().isAfter(tasksParam.getPlannedEndTime())) {
            result.fail("计划开始时间不能晚于计划结束时间!");
            return result;
        }

        return result;
    }

    /**
     * 验证父任务相关参数
     *
     * @param tasksParam 任务参数
     * @return 验证结果
     */
    private ResponseWrapper validateParentTask(TasksParam tasksParam) {
        ResponseWrapper result = new ResponseWrapper();

        // 验证父任务是否存在
        if (tasksParam.getParentId() != null && !tasksParam.getParentId().isEmpty()) {
            Tasks parentTask = tasksMapper.selectByPrimaryKey(tasksParam.getParentId());
            if (parentTask == null) {
                result.fail("指定的父任务不存在!");
                return result;
            }
        }

        return result;
    }

    /**
     * 验证编辑任务时的父任务相关参数
     *
     * @param tasksParam 任务参数
     * @return 验证结果
     */
    private ResponseWrapper validateParentTaskForEdit(TasksParam tasksParam) {
        ResponseWrapper result = new ResponseWrapper();

        // 验证父任务是否存在
        if (tasksParam.getParentId() != null && !tasksParam.getParentId().isEmpty()) {
            Tasks parentTask = tasksMapper.selectByPrimaryKey(tasksParam.getParentId());
            if (parentTask == null) {
                result.fail("指定的父任务不存在!");
                return result;
            }

            // 防止循环引用（任务不能成为自己的父任务）
            if (tasksParam.getParentId().equals(tasksParam.getId())) {
                result.fail("任务不能成为自己的父任务!");
                return result;
            }

            // 防止循环引用（检查父任务是否是当前任务的子任务）
            if (isChildOf(tasksParam.getParentId(), tasksParam.getId())) {
                result.fail("不能将任务的子任务设置为父任务，这会造成循环引用!");
                return result;
            }
        }

        return result;
    }

    /**
     * 验证处理人信息
     *
     * @param tasksParam 任务参数
     * @return 验证结果
     */
    private ResponseWrapper validateAssigneeInfo(TasksParam tasksParam) {
        ResponseWrapper result = new ResponseWrapper();

        // 调用系统用户服务查询用户信息
        ObjectWrapper<GetSysUserResponseDTO> userInfoById = systemClient.getUserInfoById(tasksParam.getAssigneeId());
        if (userInfoById.verifyFail()) {
            log.error("Error occurred while getting user info for assignee: {}", tasksParam.getAssigneeId());
            result.fail("获取处理信息失败!");
            return result;
        }

        if (userInfoById.getData() == null) {
            result.fail("传入的处理人不存在!");
            return result;
        }

        //验证处理人状态
        StatusEnum statusEnum = StatusEnum.getEnumByCode(userInfoById.getData().status());
        if (statusEnum != StatusEnum.ENABLE) {
            result.fail("处理人未启用!");
            return result;
        }

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper editTask(TasksParam tasksParam) {
        ResponseWrapper result = new ResponseWrapper();

        // 验证任务是否存在
        Tasks existingTask = tasksMapper.selectByPrimaryKey(tasksParam.getId());
        if (null == existingTask) {
            result.fail("传入的任务信息不存在!");
            return result;
        }

        // 验证任务状态是否允许编辑
        TaskStatusEnum taskStatus = TaskStatusEnum.getEnumByCode(existingTask.getStatus());
        if (taskStatus == TaskStatusEnum.PUBLISHED ||
                taskStatus == TaskStatusEnum.IN_PROGRESS ||
                taskStatus == TaskStatusEnum.COMPLETED) {
            result.fail("任务已发布或正在进行中，不允许编辑基本信息!");
            return result;
        }

        // 检查当前用户是否为任务创建者
        if (!existingTask.getCreatorId().equals(SecurityUtils.getUserId())) {
            result.fail("只有任务创建者才能编辑任务!");
            return result;
        }

        // 验证参数
        ResponseWrapper validationResponse = validateTaskParamsForEdit(tasksParam);
        if (validationResponse.verifyFail()) {
            return validationResponse;
        }

        // 验证父任务相关参数
        ResponseWrapper parentValidationResult = validateParentTaskForEdit(tasksParam);
        if (parentValidationResult.verifyFail()) {
            return parentValidationResult;
        }

        // 检查父任务是否发生变化
        String oldParentId = existingTask.getParentId();
        String newParentId = tasksParam.getParentId();

        // 更新任务信息
        Tasks taskToUpdate = TasksMapStructMapper.INSTANCE.tasksParamToTasks(tasksParam);
        taskToUpdate.setUpdateBy(SecurityUtils.getUserId());
        taskToUpdate.setUpdateTime(LocalDateTime.now());
        tasksMapper.updateByPrimaryKeySelective(taskToUpdate);

        // 如果父任务发生变化，记录日志
        if (!Objects.equals(oldParentId, newParentId)) {
            log.info("任务 {} 的父任务从 {} 更改为 {}", tasksParam.getId(), oldParentId, newParentId);
        }

        // 记录任务编辑操作
        TaskOperations taskOperation = TaskOperations.builder()
                .id(TaskNoUtils.generateTaskId())
                .taskId(tasksParam.getId())
                .operationType(TaskOperationTypeEnum.EDIT.getCode())
                .operatorId(SecurityUtils.getUserId())
                .operatorName(SecurityUtils.getUserName())
                .remark(tasksParam.getRemark() != null && !tasksParam.getRemark().isEmpty() ? tasksParam.getRemark() : "任务信息已更新")
                .createTime(LocalDateTime.now())
                .build();
        taskOperationsMapper.insertSelective(taskOperation);

        return result;
    }

    @Override
    public ResponseWrapper deleteTask(String taskId) {
        ResponseWrapper result = new ResponseWrapper();

        // 验证任务是否存在
        Tasks existingTask = tasksMapper.selectByPrimaryKey(taskId);
        if (null == existingTask) {
            result.fail("传入的任务信息不存在!");
            return result;
        }

        // 检查任务状态是否允许删除（只有待发布的任务才能删除）
        if (!TaskStatusEnum.PENDING_RELEASE.getCode().equals(existingTask.getStatus())) {
            result.fail("只有待发布的任务才能删除!");
            return result;
        }

        // 检查当前用户是否为任务创建者
        if (!existingTask.getCreatorId().equals(SecurityUtils.getUserId())) {
            result.fail("只有任务创建者才能删除任务!");
            return result;
        }

        // 检查任务是否有子任务
        // 当前策略：如果任务有子任务，拒绝删除并提示用户先删除子任务
        // 这是一种保守的数据保护策略，防止误删整个任务树
        // TODO: 可考虑添加级联删除选项，在用户明确确认后删除整个任务树
        if (hasChildren(taskId)) {
            result.fail("该任务包含子任务，无法删除，请先删除所有子任务!");
            return result;
        }

        // 记录任务删除操作，包括附件信息
        StringBuilder remarkBuilder = new StringBuilder("任务已被删除");
        if (existingTask.getAttachment() != null && !existingTask.getAttachment().isEmpty()) {
            remarkBuilder.append("，原附件信息: ").append(existingTask.getAttachment());
        }

        TaskOperations taskOperation = TaskOperations.builder()
                .id(TaskNoUtils.generateTaskId())
                .taskId(taskId)
                // 使用取消操作类型记录删除
                .operationType(TaskOperationTypeEnum.CANCEL.getCode())
                .operatorId(SecurityUtils.getUserId())
                .operatorName(SecurityUtils.getUserName())
                .remark(remarkBuilder.toString())
                // 保留原任务的附件信息
                .attachment(existingTask.getAttachment())
                .createTime(LocalDateTime.now())
                .build();
        taskOperationsMapper.insertSelective(taskOperation);

        // 逻辑外键验证：查询任务相关的操作记录数量
        TaskOperationsParam param = new TaskOperationsParam();
        param.setTaskId(taskId);
        Long count = taskOperationsMapper.countTaskOperations(taskId, null, null);
        log.info("任务 {} 存在 {} 条操作记录", taskId, count);


        taskOperationsMapper.deleteByTaskId(taskId);

        // 删除任务
        tasksMapper.deleteByPrimaryKey(taskId);

        return result;
    }

    /**
     * 检查childId是否是parentId的子任务（直接或间接）
     *
     * @param parentId 父任务ID
     * @param childId  子任务ID
     * @return 如果childId是parentId的子任务则返回true，否则返回false
     */
    private boolean isChildOf(String parentId, String childId) {
        if (parentId == null || childId == null) {
            return false;
        }

        // 获取childId的父任务
        Tasks childTask = tasksMapper.selectByPrimaryKey(childId);
        if (childTask == null || childTask.getParentId() == null) {
            return false;
        }

        // 如果childTask的父任务就是parentId，则直接返回true
        if (childTask.getParentId().equals(parentId)) {
            return true;
        }

        // 递归检查childTask的父任务是否是parentId的子任务
        return isChildOf(parentId, childTask.getParentId());
    }

    /**
     * 检查指定任务是否有子任务
     *
     * @param taskId 任务ID
     * @return 是否有子任务
     */
    private boolean hasChildren(String taskId) {
        if (taskId == null || taskId.isEmpty()) {
            return false;
        }

        // 查询任务是否还有子任务
        List<Tasks> children = tasksMapper.selectTasksByParentId(taskId);
        return children != null && !children.isEmpty();
    }

    @Override
    public ObjectWrapper<TasksVO> selectTaskById(String taskId) {
        ObjectWrapper<TasksVO> result = new ObjectWrapper<>();
        // 验证任务是否存在
        Tasks selectByPrimaryKey = tasksMapper.selectByPrimaryKey(taskId);
        if (null == selectByPrimaryKey) {
            result.fail("传入的任务信息不存在!");
            return result;
        }

        // 获取任务类型信息
        if (selectByPrimaryKey.getTaskTypeId() != null) {
            TaskTypes taskTypes = taskTypesMapper.selectByPrimaryKey(selectByPrimaryKey.getTaskTypeId());
            if (taskTypes != null) {
                TasksVO tasksVO = TasksMapStructMapper.INSTANCE.tasksToTasksVO(selectByPrimaryKey);
                tasksVO.setTaskTypeName(taskTypes.getTypeName());
                tasksVO.setTaskTypeColor(taskTypes.getColor());
                result.setData(tasksVO);
                return result;
            }
        }

        TasksVO tasksVO = TasksMapStructMapper.INSTANCE.tasksToTasksVO(selectByPrimaryKey);
        // 设置是否有子任务
        List<Tasks> children = tasksMapper.selectTasksByParentId(selectByPrimaryKey.getId());
        tasksVO.setHasChildren(children != null && !children.isEmpty());
        result.setData(tasksVO);
        return result;
    }

    /**
     * 发布任务
     *
     * @param tasksParam 任务参数
     * @return {@link ResponseWrapper}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper publishTask(TasksParam tasksParam) {
        ResponseWrapper result = new ResponseWrapper();

        // 验证任务是否存在
        Tasks existingTask = tasksMapper.selectByPrimaryKey(tasksParam.getId());
        if (null == existingTask) {
            result.fail("传入的任务信息不存在!");
            return result;
        }

        // 检查任务状态是否允许发布（只有待发布状态的任务才能发布）
        if (!TaskStatusEnum.PENDING_RELEASE.getCode().equals(existingTask.getStatus())) {
            result.fail("只有待发布的任务才能执行发布操作!");
            return result;
        }

        // 检查当前用户是否为任务创建者
        if (!existingTask.getCreatorId().equals(SecurityUtils.getUserId())) {
            result.fail("只有任务创建者才能发布任务!");
            return result;
        }

        // 如果有子任务，需要检查子任务状态
        List<Tasks> childTasks = tasksMapper.selectTasksByParentId(tasksParam.getId());
        if (childTasks != null && !childTasks.isEmpty()) {
            // 检查是否有子任务已完成或已取消
            for (Tasks childTask : childTasks) {
                if (TaskStatusEnum.COMPLETED.getCode().equals(childTask.getStatus()) ||
                        TaskStatusEnum.CANCELLED.getCode().equals(childTask.getStatus())) {
                    result.fail("包含已完成或已取消的子任务，不能发布父任务!");
                    return result;
                }

                // 检查是否有子任务处理人不是当前用户但任务已签收的情况
                if (TaskStatusEnum.IN_PROGRESS.getCode().equals(childTask.getStatus()) &&
                        !childTask.getAssigneeId().equals(SecurityUtils.getUserId())) {
                    result.fail("包含已签收的子任务，且您不是该子任务的处理人，不能发布父任务!");
                    return result;
                }
            }

            // 发布所有子任务
            Tasks childTaskToUpdate = new Tasks();
            childTaskToUpdate.setStatus(TaskStatusEnum.PUBLISHED.getCode());
            childTaskToUpdate.setUpdateBy(SecurityUtils.getUserId());
            childTaskToUpdate.setUpdateTime(LocalDateTime.now());

            for (Tasks childTask : childTasks) {
                childTaskToUpdate.setId(childTask.getId());
                tasksMapper.updateByPrimaryKeySelective(childTaskToUpdate);

                // 记录子任务发布操作
                TaskOperations childTaskOperation = TaskOperations.builder()
                        .id(TaskNoUtils.generateTaskId())
                        .taskId(childTask.getId())
                        .operationType(TaskOperationTypeEnum.PUBLISH.getCode())
                        .operatorId(SecurityUtils.getUserId())
                        .operatorName(SecurityUtils.getUserName())
                        .remark("父任务发布，子任务自动发布")
                        .createTime(LocalDateTime.now())
                        .build();
                taskOperationsMapper.insertSelective(childTaskOperation);

                // 发送子任务指派通知给处理人
                notificationComponent.sendTaskPublishedNotification(childTask);
            }
        }

        // 更新任务状态为已发布
        Tasks taskToUpdate = new Tasks();
        taskToUpdate.setId(tasksParam.getId());
        taskToUpdate.setStatus(TaskStatusEnum.PUBLISHED.getCode());
        taskToUpdate.setUpdateBy(SecurityUtils.getUserId());
        taskToUpdate.setUpdateTime(LocalDateTime.now());
        tasksMapper.updateByPrimaryKeySelective(taskToUpdate);

        // 记录任务发布操作
        TaskOperations taskOperation = TaskOperations.builder()
                .id(TaskNoUtils.generateTaskId())
                .taskId(tasksParam.getId())
                .operationType(TaskOperationTypeEnum.PUBLISH.getCode())
                .operatorId(SecurityUtils.getUserId())
                .operatorName(SecurityUtils.getUserName())
                .remark(tasksParam.getRemark() != null && !tasksParam.getRemark().isEmpty() ? tasksParam.getRemark() : "任务已发布")
                .createTime(LocalDateTime.now())
                .build();
        taskOperationsMapper.insertSelective(taskOperation);

        // 发送任务指派通知给处理人
        notificationComponent.sendTaskPublishedNotification(existingTask);

        return result;
    }

    /**
     * 签收任务
     *
     * @param tasksParam 任务参数
     * @return {@link ResponseWrapper}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper claimTask(TasksParam tasksParam) {
        ResponseWrapper result = new ResponseWrapper();

        // 验证任务是否存在
        Tasks existingTask = tasksMapper.selectByPrimaryKey(tasksParam.getId());
        if (null == existingTask) {
            result.fail("传入的任务信息不存在!");
            return result;
        }

        // 检查任务状态是否允许签收（只有已发布的任务才能签收）
        if (!TaskStatusEnum.PUBLISHED.getCode().equals(existingTask.getStatus())) {
            result.fail("只有已发布的任务才能执行签收操作!");
            return result;
        }

        // 检查当前用户是否为任务指定处理人
        if (!existingTask.getAssigneeId().equals(SecurityUtils.getUserId())) {
            result.fail("只有任务指定处理人才能签收任务!");
            return result;
        }

        // 更新任务状态为进行中，并设置实际开始时间
        Tasks taskToUpdate = new Tasks();
        taskToUpdate.setId(tasksParam.getId());
        taskToUpdate.setStatus(TaskStatusEnum.IN_PROGRESS.getCode());
        taskToUpdate.setActualStartTime(LocalDateTime.now());

        // 如果计划开始和结束时间尚未设置，则使用当前时间作为计划开始时间，
        // 并根据任务类型和优先级计算计划结束时间
        if (existingTask.getPlannedStartTime() == null) {
            taskToUpdate.setPlannedStartTime(LocalDateTime.now());
        }
        if (existingTask.getPlannedEndTime() == null) {
            // 简单处理：计划结束时间设置为7天后
            taskToUpdate.setPlannedEndTime(LocalDateTime.now().plusDays(7));
        }

        taskToUpdate.setUpdateBy(SecurityUtils.getUserId());
        taskToUpdate.setUpdateTime(LocalDateTime.now());
        tasksMapper.updateByPrimaryKeySelective(taskToUpdate);

        // 记录任务签收操作
        TaskOperations taskOperation = TaskOperations.builder()
                .id(TaskNoUtils.generateTaskId())
                .taskId(tasksParam.getId())
                .operationType(TaskOperationTypeEnum.CLAIM.getCode())
                .operatorId(SecurityUtils.getUserId())
                .operatorName(SecurityUtils.getUserName())
                .remark(tasksParam.getRemark() != null && !tasksParam.getRemark().isEmpty() ? tasksParam.getRemark() : "任务已签收")
                .createTime(LocalDateTime.now())
                .build();
        taskOperationsMapper.insertSelective(taskOperation);

        // 发送任务签收通知给创建人
        notificationComponent.sendTaskAcceptedNotification(existingTask, SecurityUtils.getUserName());

        return result;
    }

    /**
     * 更新任务进度
     *
     * @param tasksParam 任务参数
     * @return {@link ResponseWrapper}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper updateProgress(TasksParam tasksParam) {
        ResponseWrapper result = new ResponseWrapper();

        // 验证任务是否存在
        Tasks existingTask = tasksMapper.selectByPrimaryKey(tasksParam.getId());
        if (null == existingTask) {
            result.fail("传入的任务信息不存在!");
            return result;
        }

        // 检查任务状态是否允许更新进度（进行中的任务才能更新进度）
        if (!TaskStatusEnum.IN_PROGRESS.getCode().equals(existingTask.getStatus())) {
            result.fail("只有进行中的任务才能更新进度!");
            return result;
        }

        // 检查当前用户是否为任务指定处理人
        if (!existingTask.getAssigneeId().equals(SecurityUtils.getUserId())) {
            result.fail("只有任务指定处理人才能更新任务进度!");
            return result;
        }

        // 更新任务信息
        Tasks taskToUpdate = new Tasks();
        taskToUpdate.setId(tasksParam.getId());
        taskToUpdate.setUpdateBy(SecurityUtils.getUserId());
        taskToUpdate.setUpdateTime(LocalDateTime.now());
        // 可以更新其他进度相关字段
        tasksMapper.updateByPrimaryKeySelective(taskToUpdate);

        // 记录任务进度更新操作
        TaskOperations taskOperation = TaskOperations.builder()
                .id(TaskNoUtils.generateTaskId())
                .taskId(tasksParam.getId())
                .operationType(TaskOperationTypeEnum.PROGRESS_UPDATE.getCode())
                .operatorId(SecurityUtils.getUserId())
                .operatorName(SecurityUtils.getUserName())
                .progressPercent(tasksParam.getProgressPercent())
                .remark(tasksParam.getRemark() != null && !tasksParam.getRemark().isEmpty() ? tasksParam.getRemark() : "任务进度已更新")
                .createTime(LocalDateTime.now())
                .build();
        taskOperationsMapper.insertSelective(taskOperation);

        // 发送任务进度更新通知给创建人
        notificationComponent.sendTaskProgressUpdateNotification(existingTask, tasksParam.getProgressPercent(), tasksParam.getRemark());

        return result;
    }

    /**
     * 完成任务
     *
     * @param tasksParam 任务参数
     * @return {@link ResponseWrapper}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper completeTask(TasksParam tasksParam) {
        ResponseWrapper result = new ResponseWrapper();

        // 验证任务是否存在
        Tasks existingTask = tasksMapper.selectByPrimaryKey(tasksParam.getId());
        if (null == existingTask) {
            result.fail("传入的任务信息不存在!");
            return result;
        }

        // 检查任务状态是否允许完成（进行中的任务才能完成）
        if (!TaskStatusEnum.IN_PROGRESS.getCode().equals(existingTask.getStatus())) {
            result.fail("只有进行中的任务才能执行完成操作!");
            return result;
        }

        // 检查当前用户是否为任务处理人
        if (!existingTask.getAssigneeId().equals(SecurityUtils.getUserId())) {
            result.fail("只有任务处理人才能完成任务!");
            return result;
        }

        // 如果是父任务完成，检查是否所有子任务已完成或已取消
        if (existingTask.getParentId() == null) {
            List<Tasks> childTasks = tasksMapper.selectTasksByParentId(tasksParam.getId());
            if (childTasks != null && !childTasks.isEmpty()) {
                boolean allChildrenCompletedOrCancelled = childTasks.stream()
                        .allMatch(child -> TaskStatusEnum.COMPLETED.getCode().equals(child.getStatus())
                                || TaskStatusEnum.CANCELLED.getCode().equals(child.getStatus()));

                if (!allChildrenCompletedOrCancelled) {
                    result.fail("父任务完成前，必须先完成或取消所有子任务!");
                    return result;
                }
            }
        }

        // 更新任务状态为已完成，并设置实际结束时间
        Tasks taskToUpdate = new Tasks();
        taskToUpdate.setId(tasksParam.getId());
        taskToUpdate.setStatus(TaskStatusEnum.COMPLETED.getCode());
        taskToUpdate.setActualEndTime(LocalDateTime.now());
        taskToUpdate.setUpdateBy(SecurityUtils.getUserId());
        taskToUpdate.setUpdateTime(LocalDateTime.now());
        tasksMapper.updateByPrimaryKeySelective(taskToUpdate);

        // 记录任务完成操作
        TaskOperations taskOperation = TaskOperations.builder()
                .id(TaskNoUtils.generateTaskId())
                .taskId(tasksParam.getId())
                .operationType(TaskOperationTypeEnum.COMPLETE.getCode())
                .operatorId(SecurityUtils.getUserId())
                .operatorName(SecurityUtils.getUserName())
                .remark(tasksParam.getRemark() != null && !tasksParam.getRemark().isEmpty() ? tasksParam.getRemark() : "任务已完成")
                .createTime(LocalDateTime.now())
                .build();
        taskOperationsMapper.insertSelective(taskOperation);

        // 发送任务完成通知给创建人
        notificationComponent.sendTaskCompletedNotification(existingTask,
                SecurityUtils.getUserName(),
                LocalDateTime.now(),
                tasksParam.getRemark() != null && !tasksParam.getRemark().isEmpty() ? tasksParam.getRemark() : "任务已完成");

        return result;
    }

    /**
     * 关闭任务
     *
     * @param tasksParam 任务参数
     * @return {@link ResponseWrapper}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper closeTask(TasksParam tasksParam) {
        ResponseWrapper result = new ResponseWrapper();

        // 验证任务是否存在
        Tasks existingTask = tasksMapper.selectByPrimaryKey(tasksParam.getId());
        if (null == existingTask) {
            result.fail("传入的任务信息不存在!");
            return result;
        }

        // 检查任务状态是否允许关闭（已完成、已取消的任务才能关闭）
        TaskStatusEnum currentStatus = TaskStatusEnum.getEnumByCode(existingTask.getStatus());
        if (currentStatus != TaskStatusEnum.COMPLETED &&
                currentStatus != TaskStatusEnum.CANCELLED) {
            result.fail("只有已完成或已取消的任务才能执行关闭操作!");
            return result;
        }

        // 检查当前用户是否有权限关闭任务
        boolean hasPermission = false;
        // 任务创建者可以关闭任务
        if (existingTask.getCreatorId().equals(SecurityUtils.getUserId())) {
            hasPermission = true;
        }
        // 任务处理人可以关闭任务
        else if (existingTask.getAssigneeId().equals(SecurityUtils.getUserId())) {
            hasPermission = true;
        }

        if (!hasPermission) {
            result.fail("只有任务创建者或指定处理人才能关闭任务!");
            return result;
        }

        // 如果是父任务关闭，同时关闭所有子任务
        if (existingTask.getParentId() == null) {
            List<Tasks> childTasks = tasksMapper.selectTasksByParentId(tasksParam.getId());
            if (childTasks != null && !childTasks.isEmpty()) {
                Tasks childTaskToUpdate = new Tasks();
                childTaskToUpdate.setStatus(TaskStatusEnum.CLOSED.getCode());
                childTaskToUpdate.setUpdateBy(SecurityUtils.getUserId());
                childTaskToUpdate.setUpdateTime(LocalDateTime.now());

                for (Tasks childTask : childTasks) {
                    // 只关闭非已取消和非已完成的子任务
                    if (!TaskStatusEnum.CANCELLED.getCode().equals(childTask.getStatus()) &&
                            !TaskStatusEnum.COMPLETED.getCode().equals(childTask.getStatus())) {
                        childTaskToUpdate.setId(childTask.getId());
                        tasksMapper.updateByPrimaryKeySelective(childTaskToUpdate);

                        // 记录子任务关闭操作
                        TaskOperations childTaskOperation = TaskOperations.builder()
                                .id(TaskNoUtils.generateTaskId())
                                .taskId(childTask.getId())
                                .operationType(TaskOperationTypeEnum.CLOSE.getCode())
                                .operatorId(SecurityUtils.getUserId())
                                .operatorName(SecurityUtils.getUserName())
                                .remark("父任务关闭，子任务自动关闭")
                                .createTime(LocalDateTime.now())
                                .build();
                        taskOperationsMapper.insertSelective(childTaskOperation);

                        // 发送子任务关闭通知
                        notificationComponent.sendTaskClosedNotification(childTask,
                                "父任务关闭，子任务自动关闭",
                                new Date());
                    }
                }
            }
        }

        // 更新任务状态为已关闭
        Tasks taskToUpdate = new Tasks();
        taskToUpdate.setId(tasksParam.getId());
        taskToUpdate.setStatus(TaskStatusEnum.CLOSED.getCode());
        taskToUpdate.setUpdateBy(SecurityUtils.getUserId());
        taskToUpdate.setUpdateTime(LocalDateTime.now());
        tasksMapper.updateByPrimaryKeySelective(taskToUpdate);

        // 记录任务关闭操作
        TaskOperations taskOperation = TaskOperations.builder()
                .id(TaskNoUtils.generateTaskId())
                .taskId(tasksParam.getId())
                .operationType(TaskOperationTypeEnum.CLOSE.getCode())
                .operatorId(SecurityUtils.getUserId())
                .operatorName(SecurityUtils.getUserName())
                .remark(tasksParam.getRemark() != null && !tasksParam.getRemark().isEmpty() ? tasksParam.getRemark() : "任务已关闭")
                .createTime(LocalDateTime.now())
                .build();
        taskOperationsMapper.insertSelective(taskOperation);

        // 发送任务关闭通知
        notificationComponent.sendTaskClosedNotification(existingTask,
                tasksParam.getRemark() != null && !tasksParam.getRemark().isEmpty() ? tasksParam.getRemark() : "任务已关闭",
                new Date());

        return result;
    }

    /**
     * 取消任务
     *
     * @param tasksParam 任务参数
     * @return {@link ResponseWrapper}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper cancelTask(TasksParam tasksParam) {
        ResponseWrapper result = new ResponseWrapper();

        // 验证任务是否存在
        Tasks existingTask = tasksMapper.selectByPrimaryKey(tasksParam.getId());
        if (null == existingTask) {
            result.fail("传入的任务信息不存在!");
            return result;
        }

        // 检查任务状态是否允许取消（待发布、已发布、进行中的任务才能取消）
        TaskStatusEnum currentStatus = TaskStatusEnum.getEnumByCode(existingTask.getStatus());
        if (currentStatus != TaskStatusEnum.PENDING_RELEASE &&
                currentStatus != TaskStatusEnum.PUBLISHED &&
                currentStatus != TaskStatusEnum.IN_PROGRESS) {
            result.fail("当前任务状态不允许取消操作!");
            return result;
        }

        // 检查当前用户是否有权限取消任务
        boolean hasPermission = false;
        // 任务创建者可以取消任务
        if (existingTask.getCreatorId().equals(SecurityUtils.getUserId())) {
            hasPermission = true;
        }
        // 任务处理人可以取消任务
        else if (existingTask.getAssigneeId().equals(SecurityUtils.getUserId())) {
            hasPermission = true;
        }

        if (!hasPermission) {
            result.fail("只有任务创建者或指定处理人才能取消任务!");
            return result;
        }

        // 如果是父任务取消，同时取消所有子任务
        if (existingTask.getParentId() == null) {
            List<Tasks> childTasks = tasksMapper.selectTasksByParentId(tasksParam.getId());
            if (childTasks != null && !childTasks.isEmpty()) {
                Tasks childTaskToUpdate = new Tasks();
                childTaskToUpdate.setStatus(TaskStatusEnum.CANCELLED.getCode());
                childTaskToUpdate.setUpdateBy(SecurityUtils.getUserId());
                childTaskToUpdate.setUpdateTime(LocalDateTime.now());

                for (Tasks childTask : childTasks) {
                    // 只取消非已完成和非已取消的子任务
                    if (!TaskStatusEnum.COMPLETED.getCode().equals(childTask.getStatus()) &&
                            !TaskStatusEnum.CANCELLED.getCode().equals(childTask.getStatus())) {
                        childTaskToUpdate.setId(childTask.getId());
                        tasksMapper.updateByPrimaryKeySelective(childTaskToUpdate);

                        // 记录子任务取消操作
                        TaskOperations childTaskOperation = TaskOperations.builder()
                                .id(TaskNoUtils.generateTaskId())
                                .taskId(childTask.getId())
                                .operationType(TaskOperationTypeEnum.CANCEL.getCode())
                                .operatorId(SecurityUtils.getUserId())
                                .operatorName(SecurityUtils.getUserName())
                                .remark("父任务取消，子任务自动取消")
                                .createTime(LocalDateTime.now())
                                .build();
                        taskOperationsMapper.insertSelective(childTaskOperation);

                        // 发送子任务取消通知
                        notificationComponent.sendTaskCancelledNotification(childTask,
                                "父任务取消，子任务自动取消",
                                new Date());
                    }
                }
            }
        }

        // 更新任务状态为已取消
        Tasks taskToUpdate = new Tasks();
        taskToUpdate.setId(tasksParam.getId());
        taskToUpdate.setStatus(TaskStatusEnum.CANCELLED.getCode());
        taskToUpdate.setUpdateBy(SecurityUtils.getUserId());
        taskToUpdate.setUpdateTime(LocalDateTime.now());
        tasksMapper.updateByPrimaryKeySelective(taskToUpdate);

        // 记录任务取消操作
        TaskOperations taskOperation = TaskOperations.builder()
                .id(TaskNoUtils.generateTaskId())
                .taskId(tasksParam.getId())
                .operationType(TaskOperationTypeEnum.CANCEL.getCode())
                .operatorId(SecurityUtils.getUserId())
                .operatorName(SecurityUtils.getUserName())
                .remark(tasksParam.getRemark() != null && !tasksParam.getRemark().isEmpty() ? tasksParam.getRemark() : "任务已取消")
                .createTime(LocalDateTime.now())
                .build();
        taskOperationsMapper.insertSelective(taskOperation);

        // 发送任务取消通知
        notificationComponent.sendTaskCancelledNotification(existingTask,
                tasksParam.getRemark() != null && !tasksParam.getRemark().isEmpty() ? tasksParam.getRemark() : "任务已取消",
                new Date());

        return result;
    }

    /**
     * 转派任务
     *
     * @param tasksParam 任务参数
     * @return {@link ResponseWrapper}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper reassignTask(TasksParam tasksParam) {
        ResponseWrapper result = new ResponseWrapper();

        // 验证任务是否存在
        Tasks existingTask = tasksMapper.selectByPrimaryKey(tasksParam.getId());
        if (null == existingTask) {
            result.fail("传入的任务信息不存在!");
            return result;
        }

        // 检查任务状态是否允许转派（待发布、已发布、进行中的任务才能转派）
        TaskStatusEnum currentStatus = TaskStatusEnum.getEnumByCode(existingTask.getStatus());
        if (currentStatus != TaskStatusEnum.PENDING_RELEASE &&
                currentStatus != TaskStatusEnum.PUBLISHED &&
                currentStatus != TaskStatusEnum.IN_PROGRESS) {
            result.fail("当前任务状态不允许转派操作!");
            return result;
        }

        // 检查当前用户是否有权限转派任务
        boolean hasPermission = false;
        // 任务创建者可以转派任务
        if (existingTask.getCreatorId().equals(SecurityUtils.getUserId())) {
            hasPermission = true;
        }
        // 任务处理人可以转派任务
        else if (existingTask.getAssigneeId().equals(SecurityUtils.getUserId())) {
            hasPermission = true;
        }

        if (!hasPermission) {
            result.fail("只有任务创建者或指定处理人才能转派任务!");
            return result;
        }

        // 验证指定的处理人是否存在,姓名是否正确
        ResponseWrapper userValidationResult = validateAssigneeInfo(tasksParam);
        if (userValidationResult.verifyFail()) {
            return userValidationResult;
        }

        // 更新任务的处理人信息
        Tasks taskToUpdate = new Tasks();
        taskToUpdate.setId(tasksParam.getId());
        taskToUpdate.setAssigneeId(tasksParam.getAssigneeId());
        taskToUpdate.setAssigneeName(tasksParam.getAssigneeName());
        taskToUpdate.setUpdateBy(SecurityUtils.getUserId());
        taskToUpdate.setUpdateTime(LocalDateTime.now());
        tasksMapper.updateByPrimaryKeySelective(taskToUpdate);

        // 记录任务转派操作
        TaskOperations taskOperation = TaskOperations.builder()
                .id(TaskNoUtils.generateTaskId())
                .taskId(tasksParam.getId())
                .operationType(TaskOperationTypeEnum.REASSIGN.getCode())
                .operatorId(SecurityUtils.getUserId())
                .operatorName(SecurityUtils.getUserName())
                .remark(tasksParam.getRemark() != null && !tasksParam.getRemark().isEmpty() ? tasksParam.getRemark() : "任务已转派给: " + tasksParam.getAssigneeName())
                .createTime(LocalDateTime.now())
                .build();
        taskOperationsMapper.insertSelective(taskOperation);

        // 发送任务转派通知给新的处理人
        Tasks updatedTask = new Tasks();
        updatedTask.setId(tasksParam.getId());
        updatedTask.setTitle(existingTask.getTitle());
        updatedTask.setDescription(existingTask.getDescription());
        updatedTask.setAssigneeId(tasksParam.getAssigneeId());
        updatedTask.setAssigneeName(tasksParam.getAssigneeName());
        notificationComponent.sendTaskAssignedNotification(updatedTask);

        return result;
    }


}